package org.donald.date;

import java.time.Clock;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.ZoneId;
import java.time.ZonedDateTime;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Java 8引入了新的日期时间API（JSR
 * 310）改进了日期时间的管理。日期和时间管理一直是Java开发人员最痛苦的问题。java.util.Date和后来的java.util.
 * Calendar一点也没有改变这个情况（甚至让人们更加迷茫）。
 * 
 * 因为上面这些原因，产生了Joda-Time ，可以替换Java的日期时间API。Joda-Time深刻影响了 Java 8新的日期时间API，Java
 * 8吸收了Joda-Time的精华。新的java.time包包含了所有关于日期、时间、日期时间、时区、Instant（跟日期类似但精确到纳秒）
 * 、duration（持续时间）和时钟操作的类。设计这些API的时候很认真地考虑了这些类的不变性（从java.util.Calendar吸取的
 * 痛苦教训）。如果需要修改时间对象，会返回一个新的实例。
 * 对于Java 8的新日期时间的总体印象还是比较积极的。一部分是因为有经历实战的Joda-Time的基础，还有一部分是因为日期时间终于被认真对待而且听取了开发人员的声音。
 * @author donald 2018年3月15日 上午8:56:00
 */
public class DateDemo {
	private static final Logger log = LoggerFactory.getLogger(DateDemo.class);

	public static void main(String[] args) {
		/*
		 * 第一个类是Clock，Clock使用时区来访问当前的instant, date和time。 Clock类可以替换
		 * System.currentTimeMillis() 和 TimeZone.getDefault().
		 */
		// Get the system clock as UTC offset
		final Clock clock = Clock.systemUTC();
		log.info(clock.instant().toString());
		log.info(String.valueOf(clock.millis()));
		/*
		 * 其他类我们看看LocalTime和LocalDate。LocalDate只保存有ISO-8601日期系统的日期部分，有时区信息，
		 * 相应地，LocalTime只保存ISO-8601日期系统的时间部分，
		 * 没有时区信息。LocalDate和LocalTime都可以从Clock对象创建。
		 */
		// Get the local date and local time
		final LocalDate date = LocalDate.now();
		final LocalDate dateFromClock = LocalDate.now(clock);

		log.info(date.toString());
		log.info(dateFromClock.toString());

		// Get the local date and local time
		final LocalTime time = LocalTime.now();
		final LocalTime timeFromClock = LocalTime.now(clock);

		log.info(time.toString());
		log.info(timeFromClock.toString());
		/*
		 * LocalDateTime类合并了LocalDate和LocalTime，它保存有ISO-8601日期系统的日期和时间，但是没有时区信息。
		 */
		// Get the local date/time
		final LocalDateTime datetime = LocalDateTime.now();
		final LocalDateTime datetimeFromClock = LocalDateTime.now( clock );
		 
		log.info( datetime.toString() );
		log.info( datetimeFromClock.toString() );
		
		/*
		 * 如果您需要一个类持有日期时间和时区信息，可以使用ZonedDateTime，它保存有ISO-8601日期系统的日期和时间，而且有时区信息。
		 */
		// Get the zoned date/time
		final ZonedDateTime zonedDatetime = ZonedDateTime.now();
		final ZonedDateTime zonedDatetimeFromClock = ZonedDateTime.now( clock );
		final ZonedDateTime zonedDatetimeFromZone = ZonedDateTime.now( ZoneId.of( "America/Los_Angeles" ) );
		 
		System.out.println( zonedDatetime );
		System.out.println( zonedDatetimeFromClock );
		System.out.println( zonedDatetimeFromZone );
		
		/*
		 * Duration类，Duration持有的时间精确到纳秒。它让我们很容易计算两个日期中间的差异。
		 */
		// Get duration between two dates
		final LocalDateTime from = LocalDateTime.of( 2014, Month.APRIL, 16, 0, 0, 0 );
		final LocalDateTime to = LocalDateTime.of( 2015, Month.APRIL, 16, 23, 59, 59 );
		 
		final Duration duration = Duration.between( from, to );
		log.info( "Duration in days: {}" , duration.toDays() );
		log.info( "Duration in hours: {}" , duration.toHours() );
	}

}
